using System;

namespace Atomic.Thermodynamics.StateEquations
{
	[Serializable]
	public class HexagonalVolumeEnergyPoint : VolumeEnergyPoint, IHexagonalVolumeEnergyPoint
	{
		public HexagonalVolumeEnergyPoint(double a, double c, int unitCells, double energy)
			: base(HexagonalVolume(a, c, unitCells), energy)
		{
			A = a;
			C = c;
			Ratio = c / a;
			UnitCells = unitCells;
		}

		public static double HexagonalVolume(double a, double c)
		{
			if (a <= 0.0 || c <= 0.0)
			{
				throw new ArgumentOutOfRangeException();
			}

			// Volume of 2-atom hexagonal unit cell.
			return 0.5 * Math.Sqrt(3.0) * a * a * c;
			//return StructureHelper.CreateHexagonalStructure(a, c, Atom.Undefined).Volume;
		}

		public static double HexagonalVolume(double a, double c, int unitCells)
		{
			if (unitCells < 1)
			{
				throw new ArgumentOutOfRangeException();
			}

			return HexagonalVolume(a, c) * unitCells;
		}

		public static void HexagonalLatticeConstants(double volume, double ratio, out double a, out double c)
		{
			if (volume <= 0.0 || ratio <= 0.0)
			{
				throw new ArgumentOutOfRangeException();
			}

			// Solve for (a,c) so that V(a,c)=V and c/a=r.
			a = Math.Pow(volume / (0.5 * Math.Sqrt(3.0) * ratio), 1.0 / 3.0);
			c = a * ratio;
		}

		public static void HexagonalLatticeConstants(double volume, double ratio, int unitCells, out double a, out double c)
		{
			if (unitCells < 1)
			{
				throw new ArgumentOutOfRangeException();
			}

			HexagonalLatticeConstants(volume / unitCells, ratio, out a, out c);
		}

		public double A
		{
			get;
			private set;
		}

		public double C
		{
			get;
			private set;
		}

		public double Ratio
		{
			get;
			private set;
		}

		/// <summary>
		/// Number of 2-atom hexagonal unit cells.
		/// </summary>
		public int UnitCells
		{
			get;
			private set;
		}
	}
}
